﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting.Shell;
using Microsoft.Scripting.Runtime;

namespace Misuzilla.Crigate.Scripting
{
    [Description("DLR統合 コンテキストに切り替えます")]
    public class DLRContext : Context
    {
        public override ICollection<ContextInfo> Contexts { get { return (IsEvalEnabled ? new ContextInfo[] { new ContextInfo(typeof(IpyContext)) } : new ContextInfo[0]); } }
        //public Boolean IsEvalEnabled { get { return File.Exists(Path.Combine(CurrentSession.UserConfigDirectory, "EnableDLRDebug")); } }
        public Boolean IsEvalEnabled { get { return true; } }

        [Description("読み込まれているスクリプトを一覧表示します")]
        public void List()
        {
            DLRIntegrationHandler handler = CurrentSession.HandlerLoader.GetHandler<DLRIntegrationHandler>();
            if (handler.ScriptScopes.Keys.Count == 0)
            {
                Console.NotifyMessage("スクリプトは現在読み込まれていません。");
                return;
            }

            foreach (var key in handler.ScriptScopes.Keys)
            {
                Console.NotifyMessage(key);
            }
        }

        [Description("スクリプトを再読み込みします")]
        public void Reload()
        {
            Console.NotifyMessage("スクリプトを再読み込みします。");
            DLRIntegrationHandler handler = CurrentSession.HandlerLoader.GetHandler<DLRIntegrationHandler>();
            handler.ReloadScripts((fileName, ex) =>
            {
                Console.NotifyMessage("ファイル " + fileName + " を読み込みました。");
                if (ex != null)
                {
                    Console.NotifyMessage("実行時にエラーが発生しました:");
                    Console.NotifyMessage(ex.ToString());
                    if (ex is SyntaxErrorException)
                    {
                        SyntaxErrorException syntaxEx = ex as SyntaxErrorException;
                        Console.NotifyMessage(String.Format("  行: {0}, 列 {1}, ファイル: {2}", syntaxEx.Line, syntaxEx.Column, syntaxEx.SourcePath));
                    }
                }
            });
            Console.NotifyMessage("スクリプトを再読み込みしました。");
        }

        [Description("現在のスクリプトスコープでスクリプトを評価します")]
        public void Eval([Description("言語名またはスクリプトエンジンの名前")]
                         String languageName,
                         [Description("評価する式")]
                         String expression)
        {
            if (IsEvalEnabled)
            {
                DLRIntegrationHandler handler = CurrentSession.HandlerLoader.GetHandler<DLRIntegrationHandler>();
                Object retVal = handler.Eval(languageName, expression);
                Console.NotifyMessage(retVal == null ? "(null)" : retVal.ToString());
            }
            else
            {
                Console.NotifyMessage("Eval コマンドは現在無効化されています。");
                //ConsoleAddIn.NotifyMessage("ユーザ設定ディレクトリに EnableDLRDebug ファイルを作成することで有効になります。");
            }
        }
    }
}
